#coding=utf-8
#!/usr/bin/python
# base on UndCover
# modified by eaudouce
import sys, json, time, requests, math
sys.path.append('..')
from base.spider import Spider

class Spider(Spider):  # 元类 默认的元类 type
    site_name = 'xk_央视'
    headers = {
        'Accept-Encoding': 'gzip, deflate',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 Edg/122.0.0.0',
        'Origin': 'https://tv.cctv.com',
        'Referer': 'https://tv.cctv.com/'
    }

    pianku_configs = {
        'dsj': {'channelid': 'CHAL1460955853485115', 'fc': '电视剧'},
        'dhp': {'channelid': 'CHAL1460955899450127', 'fc': '动画片'},
        'jlp': {'channelid': 'CHAL1460955924871139', 'fc': '纪录片'},
        'tbjm': {'channelid': 'CHAL1460955953877151', 'fc': '特别节目'}
    }

    config = {
        'player': {},
        'class': [
            {'type_name': '栏目大全', 'type_id': 'lanmu'},
            {'type_name': '电视剧', 'type_id': 'dsj'},
            {'type_name': '动画片', 'type_id': 'dhp'},
            {'type_name': '纪录片', 'type_id': 'jlp'},
            {'type_name': '特别节目', 'type_id': 'tbjm'}
        ],
        'filter': {
            'lanmu': [{
                'key': 'cid',
                'name': '频道',
                'value': [{
                    'n': '全部',
                    'v': ''
                }, {
                    'n': 'CCTV-1综合',
                    'v': 'EPGC1386744804340101'
                }, {
                    'n': 'CCTV-2财经',
                    'v': 'EPGC1386744804340102'
                }, {
                    'n': 'CCTV-3综艺',
                    'v': 'EPGC1386744804340103'
                }, {
                    'n': 'CCTV-4中文国际',
                    'v': 'EPGC1386744804340104'
                }, {
                    'n': 'CCTV-5体育',
                    'v': 'EPGC1386744804340107'
                }, {
                    'n': 'CCTV-6电影',
                    'v': 'EPGC1386744804340108'
                }, {
                    'n': 'CCTV-7国防军事',
                    'v': 'EPGC1386744804340109'
                }, {
                    'n': 'CCTV-8电视剧',
                    'v': 'EPGC1386744804340110'
                }, {
                    'n': 'CCTV-9纪录',
                    'v': 'EPGC1386744804340112'
                }, {
                    'n': 'CCTV-10科教',
                    'v': 'EPGC1386744804340113'
                }, {
                    'n': 'CCTV-11戏曲',
                    'v': 'EPGC1386744804340114'
                }, {
                    'n': 'CCTV-12社会与法',
                    'v': 'EPGC1386744804340115'
                }, {
                    'n': 'CCTV-13新闻',
                    'v': 'EPGC1386744804340116'
                }, {
                    'n': 'CCTV-14少儿',
                    'v': 'EPGC1386744804340117'
                }, {
                    'n': 'CCTV-15音乐',
                    'v': 'EPGC1386744804340118'
                }, {
                    'n': 'CCTV-16奥林匹克',
                    'v': 'EPGC1634630207058998'
                }, {
                    'n': 'CCTV-17农业农村',
                    'v': 'EPGC1563932742616872'
                }, {
                    'n': 'CCTV-5+体育赛事',
                    'v': 'EPGC1468294755566101'
                }]
            }, {
                'key': 'fc',
                'name': '分类',
                'value': [{'n': '全部', 'v': ''}] + [{'n': i, 'v': i} for i in '新闻#体育#综艺#健康#生活#科教#经济#农业#法治#军事#少儿#动画#纪实#戏曲#音乐#影视'.split('#')]
            }, {
                'key': 'fl',
                'name': '首字母',
                'value': [{'n': '全部', 'v': ''}] + [{'n': chr(i), 'v': chr(i)} for i in range(ord('A'), ord('Z')+1)]
            }, {
                'key': 'year',
                'name': '年份',
                'value': [{'n': '全部', 'v': ''}] + [{'n': str(i), 'v': str(i)} for i in range(int(time.localtime().tm_year), 2007, -1)]
            }, {
                'key': 'month',
                'name': '月份',
                'value': [{'n': '全部', 'v': ''}] + [{'n': str(i).zfill(2), 'v': str(i).zfill(2)} for i in range(1, 13)]
            }],
            'dsj': [{
                'key': 'sc',
                'name': '类型',
                'value': [{'n': '全部', 'v': ''}] + [{'n': i, 'v': i} for i in '谍战#悬疑#刑侦#历史#古装#武侠#军旅#战争#喜剧#青春#言情#偶像#家庭#年代#革命#农村#都市#其他'.split('#')]
            }, {
                'key': 'area',
                'name': '地区',
                'value': [{'n': '全部', 'v': ''}] + [{'n': i, 'v': i} for i in '内地（大陆）#港澳台#欧美#日韩#其他'.split('#')]
            }, {
                'key': 'year',
                'name': '年份',
                'value': [{'n': '全部', 'v': ''}] + [{'n': str(i), 'v': str(i)} for i in range(int(time.localtime().tm_year), 1997, -1)]
            }, {
                'key': 'letter',
                'name': '首字母',
                'value': [{'n': '全部', 'v': ''}] + [{'n': chr(i), 'v': chr(i)} for i in range(ord('A'), ord('Z')+1)]
            }],
            'dhp': [{
                'key': 'sc',
                'name': '类型',
                'value': [{'n': '全部', 'v': ''}] + [{'n': i, 'v': i} for i in '亲子#搞笑#冒险#动作#宠物#体育#益智#历史#教育#校园#言情#武侠#经典#未来#古代#神话#真人#励志#热血#奇幻#童话#剧情#夺宝#其他'.split('#')]
            }, {
                'key': 'area',
                'name': '地区',
                'value': [{'n': '全部', 'v': ''}] + [{'n': i, 'v': i} for i in '内地（大陆）#港澳台#欧美'.split('#')]
            }, {
                'key': 'letter',
                'name': '首字母',
                'value': [{'n': '全部', 'v': ''}] + [{'n': chr(i), 'v': chr(i)} for i in range(ord('A'), ord('Z')+1)]
            }],
            'jlp': [{
                'key': 'channel',
                'name': '频道',
                'value': [{'n': '全部', 'v': ''}] + [{'n': i.split('$$')[0], 'v': i.split('$$')[1]} for i in 'CCTV-1 综合$$CCTV-1综合,CCTV-1高清,CCTV-1综合高清#CCTV-2 财经$$CCTV-2财经,CCTV-2高清,CCTV-2财经高清#CCTV-3 综艺$$CCTV-3综艺,CCTV-3综艺高清#CCTV-4 中文国际$$CCTV-4中文国际,CCTV-4高清,CCTV-4中文国际(亚)高清#CCTV-5 体育$$CCTV-5体育,CCTV-5体育高清#CCTV-6 电影$$CCTV-6电影,CCTV-6电影高清#CCTV-7 国防军事$$CCTV-7军事农业,CCTV-7军事农业高清,CCTV-7国防军事高清#CCTV-9 纪录$$CCTV-9纪录,CCTV-9高清,CCTV-9纪录高清#CCTV-10 科教$$CCTV-10科教,CCTV-10高清,CCTV-10科教高清#CCTV-11 戏曲$$CCTV-11戏曲#CCTV-12 社会与法$$CCTV-12社会与法,CCTV-12社会与法高清#CCTV-13 新闻$$CCTV-13新闻#CCTV-14 少儿$$CCTV-14少儿,CCTV-14少儿高清#CCTV-15 音乐$$CCTV-15音乐,CCTV-15音乐高清#CCTV-17 农业农村$$CCTV-17农业农村高清'.split('#')]
            }, {
                'key': 'sc',
                'name': '类型',
                'value': [{'n': '全部', 'v': ''}] + [{'n': i, 'v': i} for i in '人文历史#人物#军事#探索#社会#自然#时政#经济#科技'.split('#')]
            }, {
                'key': 'year',
                'name': '年份',
                'value': [{'n': '全部', 'v': ''}] + [{'n': str(i), 'v': str(i)} for i in range(int(time.localtime().tm_year), 2008, -1)]
            }, {
                'key': 'letter',
                'name': '首字母',
                'value': [{'n': '全部', 'v': ''}] + [{'n': chr(i), 'v': chr(i)} for i in range(ord('A'), ord('Z')+1)]
            }],
            'tbjm': [{
                'key': 'channel',
                'name': '频道',
                'value': [{'n': '全部', 'v': ''}] + [{'n': i.split('$$')[0], 'v': i.split('$$')[1]} for i in 'CCTV-1 综合$$CCTV-1综合,CCTV-1高清,CCTV-1综合高清#CCTV-2 财经$$CCTV-2财经,CCTV-2高清,CCTV-2财经高清#CCTV-3 综艺$$CCTV-3综艺,CCTV-3高清,CCTV-3综艺高清#CCTV-4 中文国际$$CCTV-4中文国际,CCTV-4高清,CCTV-4中文国际(亚)高清#CCTV-5 体育$$CCTV-5体育,CCTV-5高清,CCTV-5体育高清#CCTV-6 电影$$CCTV-6电影,CCTV-6高清,CCTV-6电影高清#CCTV-7 国防军事$$CCTV-7军事农业,CCTV-7高清,CCTV-7军事农业高清,CCTV-7国防军事高清#CCTV-8 电视剧$$CCTV-8电视剧,CCTV-8高清,CCTV-8电视剧高清#CCTV-9 纪录$$CCTV-9纪录,CCTV-9高清,CCTV-9纪录高清#CCTV-10 科教$$CCTV-10科教,CCTV-10高清,CCTV-10科教高清#CCTV-11 戏曲$$CCTV-11戏曲,CCTV-11高清,CCTV-11戏曲高清#CCTV-12 社会与法$$CCTV-12社会与法,CCTV-12高清,CCTV-12社会与法高清#CCTV-13 新闻$$CCTV-13新闻,CCTV-13高清,CCTV-13新闻高清#CCTV-14 少儿$$CCTV-14少儿,CCTV-14高清,CCTV-14少儿高清#CCTV-15 音乐$$CCTV-15音乐,CCTV-15高清,CCTV-15音乐高清#CCTV-17 农业农村$$CCTV-17农业农村高清'.split('#')]
            }, {
                'key': 'sc',
                'name': '类型',
                'value': [{'n': '全部', 'v': ''}] + [{'n': i, 'v': i} for i in '新闻#经济#综艺#体育#军事#影视#科教#戏曲#青少#音乐#社会#文化#公益#其他'.split('#')]
            }, {
                'key': 'letter',
                'name': '首字母',
                'value': [{'n': '全部', 'v': ''}] + [{'n': chr(i), 'v': chr(i)} for i in range(ord('A'), ord('Z')+1)]
            }]
        }
    }

    def getName(self):
        return self.site_name

    def init(self,extend=''):
        print('============{0}============'.format(extend))
        pass

    def isVideoFormat(self,url):
        pass

    def manualVideoCheck(self):
        pass

    def homeContent(self, filter):
        result = {'class': self.config['class']}
        if(filter):
            result['filters'] = self.config['filter']
        return result

    def homeVideoContent(self):
        return {'list':[]}

    def categoryContent(self, tid, pg, filter, extend):
        result = {}
        extend['p'] = pg
        if 'lanmu' == tid:
            limit = 20
            month = ''
            year = ''
            if 'month' in extend.keys():
                month = extend['month']
            if 'year' in extend.keys():
                year = extend['year']
            if year == '':
                month = ''
            prefix = year + month
            filterMap = {
                'fl':'',
                'fc':'',
                'cid':'',
                'p':pg
            }
            suffix = []
            for key in filterMap.keys():
                if key in extend.keys():
                    filterMap[key] = extend[key]
                else:
                    filterMap[key] = ''
                suffix.append('{0}={1}'.format(key, filterMap[key]))
            url = 'https://api.cntv.cn/lanmu/columnSearch?{0}&n={1}&serviceId=tvcctv&t=json'.format('&'.join(suffix), limit)
            jo = self.fetch(url, headers=self.headers).json()
            vodList = jo['response']['docs']
            videos = []
            for vod in vodList:
                lastVideo = vod['lastVIDE']['videoSharedCode']
                if len(lastVideo) == 0:
                    lastVideo = '_'
                guid = prefix+'###'+vod['column_name']+'###'+lastVideo+'###'+vod['column_logo']
                title = vod['column_name']
                img = vod['column_logo']
                videos.append({
                    'vod_id':guid,
                    'vod_name':title,
                    'vod_pic':img,
                    'vod_remarks':''
                })
            result['list'] = videos
            result['page'] = pg
            result['pagecount'] = math.ceil(int(jo['response']['numFound'])/limit)
            result['limit'] = limit
            result['total'] = int(jo['response']['numFound'])
        else:
            pianku_config = self.pianku_configs[tid]
            limit = 24
            filterMap = {
                'sc':'',
                'area':'',
                'year':'',
                'letter':'',
                'channel':'',
                'p':pg
            }
            suffix = []
            for key in filterMap.keys():
                if key in extend.keys():
                    filterMap[key] = extend[key]
                else:
                    filterMap[key] = ''
                suffix.append('{0}={1}'.format(key, filterMap[key]))
            url = 'https://api.cntv.cn/list/getVideoAlbumList?channelid={}&fc={}&n={}&{}&serviceId=tvcctv&topv=1&t=json'.format(pianku_config['channelid'], pianku_config['fc'], limit, '&'.join(suffix))
            jo = self.fetch(url, headers=self.headers).json()
            vodList = jo['data']['list']
            videos = []
            for vod in vodList:
                guid = tid+'###'+vod['title']+'###'+vod['video']['id']+'###'
                videos.append({
                    'vod_id':guid,
                    'vod_name':vod['title'],
                    'vod_pic':vod['image'],
                    'vod_remarks':vod['sc']
                })
            result['list'] = videos
            result['page'] = pg
            result['pagecount'] = math.ceil(int(jo['data']['total'])/limit)
            result['limit'] = limit
            result['total'] = int(jo['data']['total'])

        return result

    def detailContent(self, array):
        result = {
            'list':[]
        }
        tid, title, video_id, logo = array[0].split('###')

        if 'search' == tid:
            rsp = self.fetch(video_id, headers=self.headers)
            root = self.html(self.cleanText(rsp.text))
            if video_id.find('cctv.com/lm/') > -1:
                topicId = self.regStr(rsp.text, r"var\s+topicID\s*=\s*'(.*?)'")
                channel = self.regStr(rsp.text, r'<meta\s+name\s*=\s*keywords\s+content=".*?(CCTV[\S]+).*?"')
                tid = 'lanmu'
            else:
                video_id = root.xpath("//dl[@id='fpy_ind04']/dd//a/@href")[0].split('/')[-1].replace('.shtml', '')
                tid = 'pianku'

        if tid in self.pianku_configs.keys() or 'pianku' == tid:
            url = 'https://api.cntv.cn/NewVideoset/getVideoAlbumInfoByVideoId?id={}&serviceId=tvcctv&t=json'.format(video_id)
            #print(url)
            info = self.fetch(url, headers=self.headers).json()
            #print(info)
            if None == info.get('data'):
                return result
            vod = {
                'vod_id':array[0],
                'vod_name':info['data']['title'],
                'vod_pic':info['data']['image'],
                'type_name':info['data']['sc'],
                'vod_year':'',
                'vod_area':'',
                'vod_remarks':'',
                'vod_actor':'',
                'vod_director':'',
                'vod_content':info['data']['brief'],
                'vod_play_from':info['data']['fc']
            }

            #电视剧用的part/page，特别节目用page
            limit = 100
            #part = 0
            #url_format = 'https://api.cntv.cn/NewVideo/getVideoListByAlbumIdNew?id={}&serviceId=tvcctv&pub=1&mode=0&part={}&n={}&sort=asc&t=json'
            page = 1
            url_format = 'https://api.cntv.cn/NewVideo/getVideoListByAlbumIdNew?id={}&serviceId=tvcctv&pub=1&mode=0&p={}&n={}&sort=asc&t=json'
            jo = self.fetch(url_format.format(info['data']['id'], page, limit), headers=self.headers).json()
            if None == jo.get('data') or None == jo['data'].get('list'):
                return result
            last_part = jo['data']['last_part']
            if False == isinstance(last_part, int) and False == isinstance(jo['data']['total'], int):
                return result
            if False == isinstance(last_part, int):
                last_part = jo['data']['total']

            loop_count = 0
            videoList = []
            #while last_part > part:
            while last_part > (page-1)*limit:
                vodList = jo['data']['list']
                for video in vodList:
                    videoList.append(video['title']+'$'+video['guid']+',,'+video['vip_flag'])
                #part += limit
                page += 1
                loop_count += 1
                # 防bug死循环，超过300集的剧也就看前300吧
                #if part >= last_part or loop_count > 2:
                if (page-1)*limit >= last_part or loop_count > 2:
                    break
                #jo = self.fetch(url_format.format(info['data']['id'], part, limit), headers=self.headers).json()
                jo = self.fetch(url_format.format(info['data']['id'], page, limit), headers=self.headers).json()

            vod['vod_play_url'] = '#'.join(videoList)
            result['list'].append(vod)

        elif tid != 'search':
            if 'lanmu' == tid:
                date = ''
            else:
                date = tid
                if video_id == '_':
                    return {}
                lastUrl = 'https://api.cntv.cn/video/videoinfoByGuid?guid={0}&serviceId=tvcctv'.format(video_id)
                lastJo = self.fetch(lastUrl,headers=self.headers).json()
                topicId = lastJo['ctid']
                channel = lastJo['channel']
                if len(date) > 0:
                    title = date + ' ' + title

            url = 'https://api.cntv.cn/NewVideo/getVideoListByColumn?id={0}&d={1}&p=1&n=100&sort=desc&mode=0&serviceId=tvcctv&t=json'.format(topicId,date)
            jo = self.fetch(url,headers=self.headers).json()
            vodList = jo['data']['list']
            videoList = []
            for video in vodList:
                videoList.append(video['title']+'$'+video['guid'])
            if len(videoList) == 0:
                return {}
            if len(date) == 0:
                date = time.strftime('%Y', time.localtime(time.time()))
            vod = {
                'vod_id':array[0],
                'vod_name':title,
                'vod_pic':logo,
                'type_name':channel,
                'vod_year':date,
                'vod_area':'',
                'vod_remarks':date,
                'vod_actor':'',
                'vod_director':topicId,
                'vod_content':'当前页面默认只展示最新100期的内容，可在分类页面选择年份和月份进行往期节目查看。年份和月份仅影响当前页面内容，不参与分类过滤。视频默认播放可以获取到的最高帧率。'
            }

            vod['vod_play_from'] = '栏目大全'
            vod['vod_play_url'] = '#'.join(videoList)
            result['list'].append(vod)

        return result

    def searchContent(self,key,quick):
        videos = []
        rsp = self.fetch('https://search.cctv.com/search.php?qtext={}&type=video'.format(key), headers=self.headers)
        root = self.html(self.cleanText(rsp.text))
        results = root.xpath("//div[@class='search17354_ind01']/div[@class='ind01']")
        for item in results:
            url = item.xpath(".//h3//a/@href")[0]
            title = item.xpath("string(.//h3//a)").strip()
            pic = item.xpath(".//div[@class='image']//img/@src")[0]
            videos.append({
                'vod_id': 'search###{}###{}###{}'.format(title, url, pic),
                'vod_name': title,
                'vod_pic': pic,
                'vod_remarks': ''
            })
        results = root.xpath("//div[@class='search17354_ind02']//ul/li")
        for item in results:
            url = item.xpath(".//a/@href")[0]
            title = item.xpath(".//a/@title")[0]
            pic = item.xpath(".//a//img/@src")[0]
            videos.append({
                'vod_id': 'search###{}###{}###{}'.format(title, url, pic),
                'vod_name': title,
                'vod_pic': pic,
                'vod_remarks': ''
            })
        return {'list':videos}

    def playerContent(self,flag,id,vipFlags):
        result = {}
        id_split = id.split(',,')
        if len(id_split) > 1:
            id = id_split[0]

        url = 'https://vdn.apps.cntv.cn/api/getHttpVideoInfo.do?pid={0}'.format(id)
        jo = self.fetch(url,headers=self.headers).json()
        link = jo['hls_url'].strip()

        rsp = self.fetch(link,headers=self.headers)
        content = rsp.text.strip()
        arr = content.split('\n')
        urlPrefix = self.regStr(link,'(http[s]?://[a-zA-z0-9.]+)/')

        subUrl = arr[-1].split('/')
        subUrl[3] = '2000'
        subUrl[-1] = '2000.m3u8'
        hdUrl = urlPrefix + '/'.join(subUrl)

        link = urlPrefix + arr[-1]

        hdRsp = requests.head(hdUrl, headers=self.headers)
        #print(hdRsp.status_code)
        if hdRsp.status_code == 200:
            link = hdUrl

        result['parse'] = 0
        result['playUrl'] = ''
        result['url'] = link
        result['header'] = self.headers
        return result

    def localProxy(self,param):
        return [200, 'video/MP2T', action, '']
